package com.cai310.lottery.task.jclq;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cai310.lottery.entity.lottery.jclq.JclqMatch;
import com.cai310.lottery.fetch.jclq.JclqAbstractFetchParser;
import com.cai310.lottery.fetch.jclq.JclqContextHolder;
import com.cai310.lottery.fetch.jclq.JclqDXFPassFetchParser;
import com.cai310.lottery.fetch.jclq.JclqDXFSingleFetchParser;
import com.cai310.lottery.fetch.jclq.JclqFetchResult;
import com.cai310.lottery.fetch.jclq.JclqRFSFPassFetchParser;
import com.cai310.lottery.fetch.jclq.JclqRFSFSingleFetchParser;
import com.cai310.lottery.fetch.jclq.JclqSFCPassFetchParser;
import com.cai310.lottery.fetch.jclq.JclqSFCSingleFetchParser;
import com.cai310.lottery.fetch.jclq.JclqSFPassFetchParser;
import com.cai310.lottery.fetch.jclq.JclqSFSingleFetchParser;
import com.cai310.lottery.support.jclq.JclqUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

public class JclqFetchTask {
	protected final transient Logger logger = LoggerFactory.getLogger(this.getClass());

	/** 抓取任务使用的默认线程数 */
	protected static final int DEFAULT_THREADS = 4;
	/** 抓取默认的超时时间，单位（秒） */
	protected static final long DEFAULT_TIMEOUT = 20;

	protected List<Callable<JclqFetchResult>> callList;

	/** 抓取任务使用的线程数 */
	protected int nThreads = DEFAULT_THREADS;

	/** 抓取的时超时间，单位（秒） */
	protected long timeout = DEFAULT_TIMEOUT;

	public void setnThreads(int nThreads) {
		if (nThreads > 0)
			this.nThreads = nThreads;
	}

	public void setTimeout(long timeout) {
		if (timeout > 0)
			this.timeout = timeout;
	}

	protected void init() {
		if (this.callList == null) {
			this.callList = Lists.newArrayList();
			callList.add(new Callable<JclqFetchResult>() {
				private JclqAbstractFetchParser fetchParser = new JclqSFPassFetchParser();

				@Override
				public JclqFetchResult call() throws Exception {
					return fetchParser.fetch(null);
				}
			});
			callList.add(new Callable<JclqFetchResult>() {
				private JclqAbstractFetchParser fetchParser = new JclqRFSFPassFetchParser();

				@Override
				public JclqFetchResult call() throws Exception {
					return fetchParser.fetch(null);
				}
			});
			callList.add(new Callable<JclqFetchResult>() {
				private JclqAbstractFetchParser fetchParser = new JclqSFCPassFetchParser();

				@Override
				public JclqFetchResult call() throws Exception {
					return fetchParser.fetch(null);
				}
			});
			callList.add(new Callable<JclqFetchResult>() {
				private JclqAbstractFetchParser fetchParser = new JclqDXFPassFetchParser();

				@Override
				public JclqFetchResult call() throws Exception {
					return fetchParser.fetch(null);
				}
			});
			callList.add(new Callable<JclqFetchResult>() {
				private JclqAbstractFetchParser fetchParser = new JclqSFSingleFetchParser();

				@Override
				public JclqFetchResult call() throws Exception {
					return fetchParser.fetch(null);
				}
			});
			callList.add(new Callable<JclqFetchResult>() {
				private JclqAbstractFetchParser fetchParser = new JclqRFSFSingleFetchParser();

				@Override
				public JclqFetchResult call() throws Exception {
					return fetchParser.fetch(null);
				}
			});
			callList.add(new Callable<JclqFetchResult>() {
				private JclqAbstractFetchParser fetchParser = new JclqSFCSingleFetchParser();

				@Override
				public JclqFetchResult call() throws Exception {
					return fetchParser.fetch(null);
				}
			});
			callList.add(new Callable<JclqFetchResult>() {
				private JclqAbstractFetchParser fetchParser = new JclqDXFSingleFetchParser();

				@Override
				public JclqFetchResult call() throws Exception {
					return fetchParser.fetch(null);
				}
			});
		}
	}

	public void fetch() {
		init();
		if (this.callList != null && !this.callList.isEmpty()) {
			ExecutorService exec = Executors.newFixedThreadPool(this.nThreads);
			try {
				List<Future<JclqFetchResult>> futureList = exec
						.invokeAll(this.callList, this.timeout, TimeUnit.SECONDS);
				List<JclqFetchResult> resultList = Lists.newArrayList();
				Date fetchTime = new Date();
				for (Future<JclqFetchResult> future : futureList) {
					try {
						JclqFetchResult rs = future.get();
						if (rs != null) {
							resultList.add(rs);
							JclqContextHolder.updateRateData(rs.getPlayType(), rs.getPassMode(), rs.getRateData(),
									fetchTime);
						}
					}catch (Exception e) {
						this.logger.error("抓取发生异常.", e);
						continue;
					}
				}
				SortedMap<String, JclqMatch> matchMap = assembleMatchDTO(resultList);
				JclqContextHolder.updateMatchList(Lists.newArrayList(matchMap.values()));
				this.logger.info("抓取完成.");
			} catch (InterruptedException e) {
				this.logger.error("抓取发生异常.", e);
			} catch (Exception e) {
				this.logger.error("抓取发生异常.", e);
			} finally {
				exec.shutdown();
			}
		} else {
			this.logger.error("抓取任务为空.");
		}
		try {
			Thread.sleep(1);
		} catch (InterruptedException e) {
			logger.error(""+Thread.currentThread()+"sleep出错！");
		}
	}

	public static SortedMap<String, JclqMatch> assembleMatchDTO(List<JclqFetchResult> resultList) {
		SortedMap<String, JclqMatch> assembleMatchMap = Maps.newTreeMap();
		for (JclqFetchResult rs : resultList) {
			int flag = JclqUtil.getOpenFlag(rs.getPlayType(), rs.getPassMode());
			Map<String, JclqMatch> matchMap = rs.getMatchMap();
			for (Entry<String, JclqMatch> entry : matchMap.entrySet()) {
				String matchKey = entry.getKey();
				JclqMatch matchDTO = entry.getValue();

				JclqMatch assembleMatchDTO = assembleMatchMap.get(matchKey);
				if (assembleMatchDTO == null) {
					assembleMatchDTO = new JclqMatch();
				}
				if (StringUtils.isBlank(assembleMatchDTO.getGameColor())) {
					assembleMatchDTO.setGameColor(matchDTO.getGameColor());
				}
				if (StringUtils.isBlank(assembleMatchDTO.getGameName())) {
					assembleMatchDTO.setGameName(matchDTO.getGameName());
				}
				if (StringUtils.isBlank(assembleMatchDTO.getGuestTeamName())) {
					assembleMatchDTO.setGuestTeamName(matchDTO.getGuestTeamName());
				}
				if (StringUtils.isBlank(assembleMatchDTO.getHomeTeamName())) {
					assembleMatchDTO.setHomeTeamName(matchDTO.getHomeTeamName());
				}
				if (assembleMatchDTO.getSingleHandicap() == null || assembleMatchDTO.getSingleHandicap() == 0) {
					assembleMatchDTO.setSingleHandicap(matchDTO.getSingleHandicap());
				}
				if (assembleMatchDTO.getSingleTotalScore() == null || assembleMatchDTO.getSingleTotalScore() == 0) {
					assembleMatchDTO.setSingleTotalScore(matchDTO.getSingleTotalScore());
				}
				if (assembleMatchDTO.getLineId() == null || assembleMatchDTO.getLineId() == 0) {
					assembleMatchDTO.setLineId(matchDTO.getLineId());
				}
				if (assembleMatchDTO.getMatchDate() == null || assembleMatchDTO.getMatchDate() == 0) {
					assembleMatchDTO.setMatchDate(matchDTO.getMatchDate());
				}
				if (assembleMatchDTO.getMatchTime() == null) {
					assembleMatchDTO.setMatchTime(matchDTO.getMatchTime());
				}
                
				Integer openFlag = assembleMatchDTO.getOpenFlag();
				if (openFlag == null)
					openFlag = 0;
				openFlag |= flag;
				assembleMatchDTO.setOpenFlag(openFlag);
                ///修改时间大于现在的比赛不捉取
				if(matchDTO.getMatchTime().after(new Date())){
					assembleMatchMap.put(matchKey, assembleMatchDTO);
				}
			}
		}
		return assembleMatchMap;
	}
}
